﻿//-----------------------------------------------------------------------
// <copyright file="StyleCopFixerPackage.cs" company="c0x3y">
//     Copyright (c) c0x3y. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace c0x3y.StyleCopFixer
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Design;
    using System.Diagnostics;
    using System.Globalization;
    using System.Runtime.InteropServices;
    using EnvDTE;
    using EnvDTE80;
    using Microsoft.VisualStudio;
    using Microsoft.VisualStudio.OLE.Interop;
    using Microsoft.VisualStudio.Shell;
    using Microsoft.VisualStudio.Shell.Interop;
    using Microsoft.Win32;
    using c0x3y.StyleCopFixer.Objects;

    [PackageRegistration(UseManagedResourcesOnly = true)]
    [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
    [ProvideMenuResource("Menus.ctmenu", 1)]
    [Guid(GuidList.guidStyleCopFixerPkgString)]
    public sealed class StyleCopFixerPackage : Package
    {
        private DTE dte;

        protected override void Initialize()
        {
            base.Initialize();
            // Add our command handlers for menu (commands must exist in the .vsct file)
            OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
            this.dte = (DTE)GetService(typeof(DTE));
            if (null != mcs)
            {
                // Create the command for the menu item.
                CommandID menuCommandID = new CommandID(GuidList.guidStyleCopFixerCmdSet, (int)PkgCmdIDList.cmdidStyleCopFixer);
                MenuCommand menuItem = new MenuCommand(this.EditStyleCopFixerSettings, menuCommandID);
                mcs.AddCommand(menuItem);
                // Create the menu option in the error list window
                CommandID errorListCommand = new CommandID(GuidList.guidErrorListCommandSet, (int)PkgCmdIDList.commandIdErrorList);
                OleMenuCommand errorMenuItem = new OleMenuCommand(this.FixStyleCopWarnings, errorListCommand);
                errorMenuItem.BeforeQueryStatus += new System.EventHandler(this.errorMenuItem_BeforeQueryStatus);
                mcs.AddCommand(errorMenuItem);
            }
        }

        private void FixStyleCopWarnings(object sender, EventArgs e)
        {
            EnvDTE.Window window = this.dte.Windows.Item(EnvDTE80.WindowKinds.vsWindowKindErrorList);
            ErrorList myErrorList = (EnvDTE80.ErrorList)window.Object;

            object[] objer = (object[]) myErrorList.SelectedItems;
            List<StyleCopError> selectedErrors = new List<StyleCopError>();
            foreach (object item in objer)
            {
                StyleCopError styleCopError = new StyleCopError(this.dte, (item as ErrorItem).Description.Substring(0, 6));
                styleCopError.Error = item as ErrorItem;
                selectedErrors.Add(styleCopError);
            }
            foreach (StyleCopError item in selectedErrors)
            {
                switch (item.ErrorCode)
                {
                    case "SA1001":
                        Errors.SA1001.Run(this.dte, item.Error);
                        break;
                    case "SA1003":
                        Errors.SA1003.Run(this.dte, item.Error);
                        break;
                    case "SA1005":
                        Errors.SA1005.Run(this.dte, item.Error);
                        break;
                    case "SA1008":
                        Errors.SA1008.Run(this.dte, item.Error);
                        break;
                    case "SA1009":
                        Errors.SA1009.Run(this.dte, item.Error);
                        break;
                    case "SA1101":
                        Errors.SA1101.Run(this.dte, item.Error);
                        break;
                    case "SA1012":
                        Errors.SA1012.Run(this.dte, item.Error);
                        break;
                    case "SA1013":
                        Errors.SA1013.Run(this.dte, item.Error);
                        break;
                    case "SA1025":
                        Errors.SA1025.Run(this.dte, item.Error);
                        break;
                    case "SA1106":
                        Errors.SA1106.Run(this.dte, item.Error);
                        break;
                    case "SA1121":
                        Errors.SA1121.Run(this.dte, item.Error);
                        break;
                    case "SA1202":
                        Errors.SA1202 errorFixer = new Errors.SA1202();
                        errorFixer.Run(this.dte, item.Error);
                        break;
                    case "SA1210":
                    case "SA1208":
                        Errors.SA1210.Run(this.dte, item.Error);
                        break;
                    case "SA1309":
                        Errors.SA1309.Run(this.dte, item.Error);
                        break;
                    case "SA1505":
                        Errors.SA1505.Run(this.dte, item.Error);
                        break;
                    case "SA1507":
                        Errors.SA1507.Run(this.dte, item.Error);
                        break;
                    case "SA1508":
                        Errors.SA1508.Run(this.dte, item.Error);
                        break;
                    case "SA1513":
                        Errors.SA1513.Run(this.dte, item.Error);
                        break;
                    case "SA1516":
                        Errors.SA1516.Run(this.dte, item.Error);
                        break;
                    case "SA1200":
                        Errors.SA1200.Run(this.dte, item.Error);
                        break;
                    case "SA1600":
                        Errors.SA1600.Run(this.dte, item.Error);
                        break;
                    case "SA1633":
                        Errors.SA1633.Run(this.dte, item.Error);
                        break;
                }   
            }            

            this.dte.ExecuteCommand("DebuggerContextMenus.ScriptProject.RunStyleCop");
        }
        
        private void errorMenuItem_BeforeQueryStatus(object sender, System.EventArgs e)
        {
            OleMenuCommand menuItem = sender as OleMenuCommand;
            using (ErrorListProvider errorListMenu = new ErrorListProvider(this))
            {
                EnvDTE.Window window = this.dte.Windows.Item(EnvDTE80.WindowKinds.vsWindowKindErrorList);
                ErrorList myErrorList = (EnvDTE80.ErrorList)window.Object;
                if (myErrorList.ErrorItems != null)
                {
                    if (myErrorList.ErrorItems.Count > 0)
                    {
                        menuItem.Enabled = true;
                        menuItem.Visible = true;
                    }
                    else
                    {
                        menuItem.Enabled = false;
                        menuItem.Visible = false;
                    }
                }
            }
        }

        /// <summary>
        /// This function is the callback used to execute a command when the a menu item is clicked.
        /// See the Initialize method to see how the menu item is associated to this function using
        /// the OleMenuCommandService service and the MenuCommand class.
        /// </summary>
        private void EditStyleCopFixerSettings(object sender, EventArgs e)
        {
            UpdateSettings updateSettings = new UpdateSettings();
            updateSettings.Show();
        }
    }
}
